#!/usr/bin/env python3
"""
简单的抖音视频处理测试脚本
不依赖 MCP 框架，直接测试核心功能
"""

import os
import re
import json
import requests
import tempfile
import time
import random
from pathlib import Path
from typing import Optional
import urllib3
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 禁用SSL警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class SimpleDouyinTester:
    """简化版抖音视频处理测试器"""

    def __init__(self):
        # 创建会话并配置
        self.session = requests.Session()

        # 配置重试策略
        retry_strategy = Retry(
            total=3,
            backoff_factor=1,
            status_forcelist=[429, 500, 502, 503, 504],
        )
        adapter = HTTPAdapter(max_retries=retry_strategy)
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)

        # 请求头，模拟移动端访问
        self.headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Host': 'www.douyin.com',
            'Pragma': 'no-cache',
            'Referer': 'https://www.douyin.com/',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-User': '?1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'
        }

        # 移动端头部备选
        self.mobile_headers = [
            'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1',
            'Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1',
            'Mozilla/5.0 (Linux; Android 12; SM-G996U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36',
        ]

        self.api_key = os.getenv("DOUYIN_API_KEY", "sk-nhvhqrskvjvrkweyvduwsephfrsyjapvorknqztnkoojocdy")

        # 设置会话默认配置
        self.session.headers.update(self.headers)
        # 设置超时
        self.session.timeout = 30
        # 忽略SSL证书验证（仅测试用）
        self.session.verify = False

    def get_real_url(self, share_url: str) -> tuple:
        """获取真实的视频ID和URL"""
        print(f"🔗 正在解析短链: {share_url}")

        # 随机选择User-Agent
        ua = random.choice(self.mobile_headers)
        headers = self.headers.copy()
        headers['User-Agent'] = ua

        try:
            # 添加随机延迟
            time.sleep(random.uniform(1, 3))

            # 获取重定向后的URL
            response = self.session.get(
                share_url,
                headers=headers,
                allow_redirects=True,
                timeout=15,
                verify=False
            )

            print(f"📍 重定向后URL: {response.url}")

            # 从URL中提取video_id
            video_id = None
            patterns = [
                r'/video/(\d+)',
                r'video_id=(\d+)',
                r'aweme_id=(\d+)',
                r'/(\d+)/?$'
            ]

            for pattern in patterns:
                match = re.search(pattern, response.url)
                if match:
                    video_id = match.group(1)
                    break

            if not video_id:
                # 尝试从响应内容中提取
                content = response.text
                video_id_match = re.search(r'"aweme_id":"(\d+)"', content)
                if video_id_match:
                    video_id = video_id_match.group(1)

            if not video_id:
                raise ValueError("无法从URL中提取视频ID")

            print(f"🎬 提取到视频ID: {video_id}")

            # 构建标准的视频页面URL
            standard_url = f'https://www.douyin.com/video/{video_id}'

            return video_id, standard_url, response

        except requests.exceptions.SSLError as e:
            print(f"🔐 SSL错误，尝试使用不安全连接: {e}")
            # 完全禁用SSL验证重试
            response = self.session.get(
                share_url,
                headers=headers,
                allow_redirects=True,
                timeout=15,
                verify=False
            )
            return self.get_real_url(response.url)
        except Exception as e:
            print(f"❌ 获取真实URL失败: {e}")
            raise

    def parse_share_url(self, share_text: str) -> dict:
        """从分享文本中提取无水印视频链接"""
        print("🔍 正在解析分享链接...")

        # 提取分享链接
        urls = re.findall(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', share_text)
        if not urls:
            raise ValueError("未找到有效的分享链接")

        share_url = urls[0]
        print(f"📋 找到分享链接: {share_url}")

        try:
            # 第一步：获取真实URL和视频ID
            video_id, standard_url, response = self.get_real_url(share_url)

            print(f"🌐 标准视频页面: {standard_url}")

            # 第二步：获取视频页面详细信息
            print("📄 正在获取视频详细信息...")

            # 使用移动端URL格式
            mobile_url = f'https://www.iesdouyin.com/share/video/{video_id}'

            # 更新headers为移动端
            mobile_headers = {
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                'Cache-Control': 'no-cache',
                'Pragma': 'no-cache',
                'Referer': 'https://www.douyin.com/',
                'User-Agent': random.choice(self.mobile_headers)
            }

            # 添加延迟
            time.sleep(random.uniform(2, 4))

            detail_response = self.session.get(
                mobile_url,
                headers=mobile_headers,
                timeout=20,
                verify=False
            )

            if detail_response.status_code != 200:
                print(f"⚠️ 移动端页面访问失败，尝试桌面端: {detail_response.status_code}")
                # 尝试桌面端
                detail_response = self.session.get(
                    standard_url,
                    headers=self.headers,
                    timeout=20,
                    verify=False
                )

            detail_response.raise_for_status()

            # 解析页面内容
            return self.extract_video_info(detail_response.text, video_id)

        except Exception as e:
            print(f"❌ 解析失败: {e}")
            # 尝试备用方法
            return self.parse_fallback_method(share_text, video_id if 'video_id' in locals() else None)

    def extract_video_info(self, html_content: str, video_id: str) -> dict:
        """从HTML内容中提取视频信息"""
        print("🔧 正在解析HTML内容...")

        video_url = None
        title = f"douyin_{video_id}"

        # 方法1: 查找 _ROUTER_DATA
        pattern = re.compile(
            pattern=r"window\._ROUTER_DATA\s*=\s*(.*?)</script>",
            flags=re.DOTALL,
        )
        find_res = pattern.search(html_content)

        if find_res and find_res.group(1):
            try:
                json_data = json.loads(find_res.group(1).strip())
                print("✅ 找到 _ROUTER_DATA")

                # 查找视频数据
                loader_data = json_data.get("loaderData", {})
                for key in loader_data:
                    if "video" in key or "note" in key:
                        video_info_res = loader_data[key].get("videoInfoRes", {})
                        if "item_list" in video_info_res:
                            data = video_info_res["item_list"][0]
                            video_url = data["video"]["play_addr"]["url_list"][0].replace("playwm", "play")
                            title = data.get("desc", "").strip() or f"douyin_{video_id}"
                            break
            except Exception as e:
                print(f"⚠️ 解析 _ROUTER_DATA 失败: {e}")

        # 方法2: 查找其他可能的数据结构
        if not video_url:
            print("🔍 尝试其他解析方法...")

            # 查找 SSR数据
            ssr_pattern = r'window\.__INITIAL_STATE__\s*=\s*({.*?});'
            ssr_match = re.search(ssr_pattern, html_content, re.DOTALL)

            if ssr_match:
                try:
                    ssr_data = json.loads(ssr_match.group(1))
                    print("✅ 找到 __INITIAL_STATE__")
                    # 这里需要根据实际数据结构调整
                except Exception as e:
                    print(f"⚠️ 解析 __INITIAL_STATE__ 失败: {e}")

            # 查找直接的视频链接
            video_patterns = [
                r'"play_addr":\s*{\s*"url_list":\s*\[\s*"([^"]+)"',
                r'"video_url":\s*"([^"]+)"',
                r'playAddr":\s*"([^"]+)"'
            ]

            for pattern in video_patterns:
                matches = re.findall(pattern, html_content)
                if matches:
                    video_url = matches[0].replace("playwm", "play")
                    print(f"✅ 通过正则找到视频链接: {video_url[:50]}...")
                    break

        # 清理标题中的非法字符
        if title and title != f"douyin_{video_id}":
            title = re.sub(r'[\\/:*?"<>|]', '_', title)

        if not video_url:
            # 如果都没找到，尝试构造可能的链接
            print("⚠️ 无法解析视频链接，尝试构造默认链接")
            video_url = f"https://aweme.snssdk.com/aweme/v1/play/?video_id={video_id}&line=0&ratio=720p&media_type=4&vr_type=0&improve_bitrate=0&is_play_url=1&is_support_h265=0&source=PackSourceEnum_PUBLISH"

        result = {
            "url": video_url,
            "title": title,
            "video_id": video_id
        }

        print("✅ 视频信息提取完成!")
        return result

    def parse_fallback_method(self, share_text: str, video_id: str = None) -> dict:
        """备用解析方法"""
        print("🔄 使用备用解析方法...")

        if not video_id:
            # 从分享文本中提取可能的ID
            id_patterns = [
                r'video/(\d+)',
                r'aweme_id=(\d+)',
                r'/(\d{15,20})',
            ]

            for pattern in id_patterns:
                match = re.search(pattern, share_text)
                if match:
                    video_id = match.group(1)
                    break

        if not video_id:
            video_id = "unknown"

        # 构造基本信息
        result = {
            "url": f"https://www.douyin.com/video/{video_id}",  # 占位符
            "title": f"douyin_{video_id}",
            "video_id": video_id,
            "error": "使用备用方法，可能需要手动获取视频链接"
        }

        print("⚠️ 备用方法完成，请注意检查结果")
        return result

    def test_download_video(self, video_info: dict) -> bool:
        """测试视频下载（只下载前 1MB 用于测试）"""
        print("📥 正在测试视频下载...")

        if 'error' in video_info:
            print(f"⚠️ 跳过下载测试，因为: {video_info['error']}")
            return False

        try:
            # 只下载前 1MB 用于测试
            headers = self.headers.copy()
            headers['Range'] = 'bytes=0-1048576'  # 1MB
            headers['User-Agent'] = random.choice(self.mobile_headers)

            # 添加延迟
            time.sleep(random.uniform(1, 2))

            response = self.session.get(
                video_info['url'],
                headers=headers,
                stream=True,
                timeout=15,
                verify=False
            )

            print(f"📊 响应状态: {response.status_code}")

            if response.status_code == 403:
                print("🔐 访问被拒绝，可能需要更新请求头或使用代理")
                return False
            elif response.status_code == 404:
                print("❌ 视频不存在或链接已失效")
                return False
            elif response.status_code not in [200, 206]:  # 206是部分内容响应
                print(f"⚠️ 非预期状态码: {response.status_code}")
                return False

            # 检查响应
            content_length = response.headers.get('content-length', 0)
            content_type = response.headers.get('content-type', '未知')

            print(f"📏 内容长度: {content_length} bytes")
            print(f"📋 内容类型: {content_type}")

            # 读取一小部分数据验证
            chunk = next(response.iter_content(chunk_size=1024), None)
            if chunk:
                print(f"📦 获取到数据块大小: {len(chunk)} bytes")
                # 检查是否是视频数据（简单检查）
                if chunk[:4] in [b'ftyp', b'\x00\x00\x00'] or b'mp4' in chunk[:100].lower():
                    print("✅ 视频下载测试成功! (已验证为视频数据)")
                    return True
                else:
                    print("⚠️ 数据可能不是视频格式")
                    print(f"前64字节: {chunk[:64]}")
                    return False
            else:
                print("❌ 无法获取视频数据")
                return False

        except requests.exceptions.SSLError as e:
            print(f"🔐 SSL错误: {e}")
            print("💡 建议: 使用代理或VPN，或更新SSL配置")
            return False
        except Exception as e:
            print(f"❌ 视频下载测试失败: {str(e)}")
            return False

    def test_api_connection(self) -> bool:
        """测试语音识别 API 连接"""
        print("🔌 正在测试 API 连接...")

        if not self.api_key:
            print("❌ 未设置 API 密钥")
            return False

        api_base_url = "https://api.siliconflow.cn/v1/audio/transcriptions"
        headers = {"Authorization": f"Bearer {self.api_key}"}

        try:
            # 发送一个简单的测试请求
            test_url = "https://api.siliconflow.cn/v1/models"
            response = self.session.get(test_url, headers=headers, timeout=10, verify=False)
            print(f"📊 API 响应状态: {response.status_code}")

            if response.status_code == 200:
                print("✅ API 连接测试成功!")
                return True
            elif response.status_code == 401:
                print("🔑 API 密钥无效")
                return False
            else:
                print(f"⚠️ API 返回状态码: {response.status_code}")
                return False
        except Exception as e:
            print(f"❌ API 连接测试失败: {str(e)}")
            return False

    def test_alternative_apis(self):
        """测试其他可用的抖音API"""
        print("🔄 测试替代API方案...")

        alternative_apis = [
            {
                "name": "API方案1",
                "url": "https://api.douyin.wtf/api/hybrid/video_data",
                "method": "GET"
            },
            {
                "name": "API方案2",
                "url": "https://www.iesdouyin.com/aweme/v1/web/aweme/detail/",
                "method": "GET"
            }
        ]

        for api in alternative_apis:
            try:
                print(f"🧪 测试 {api['name']}: {api['url']}")
                response = self.session.get(api['url'], timeout=10, verify=False)
                print(f"   响应状态: {response.status_code}")
                if response.status_code == 200:
                    print(f"   ✅ {api['name']} 可用")
                else:
                    print(f"   ❌ {api['name']} 不可用")
            except Exception as e:
                print(f"   ❌ {api['name']} 测试失败: {e}")


def test_network_connectivity():
    """测试网络连通性"""
    print("🌐 测试网络连通性...")

    test_urls = [
        "https://www.baidu.com",
        "https://www.douyin.com",
        "https://api.siliconflow.cn",
    ]

    for url in test_urls:
        try:
            response = requests.get(url, timeout=5, verify=False)
            print(f"✅ {url}: {response.status_code}")
        except Exception as e:
            print(f"❌ {url}: {e}")


def main():
    """主测试函数"""
    print("🚀 开始抖音视频处理功能测试")
    print("=" * 60)

    # 首先测试网络连通性
    test_network_connectivity()
    print("\n" + "=" * 60)

    # 测试用的抖音分享链接
    # 请替换为真实的抖音分享链接
    test_share_links = [
        # 示例格式，请替换为真实链接
        """4.84 复制打开抖音，看看【用户名的作品】视频标题 https://v.douyin.com/iRNBho6u/ 复制此链接""",
        # 你可以添加更多测试链接
    ]

    print("⚠️  重要提示:")
    print("1. 请将测试链接替换为真实的抖音分享链接")
    print("2. 当前抖音有严格的反爬虫机制，可能需要:")
    print("   - 使用代理/VPN")
    print("   - 更新User-Agent")
    print("   - 添加更多随机延迟")
    print("3. SSL错误可能需要系统级别的网络配置调整")
    print()

    # 让用户输入真实链接
    try:
        user_link = input("请粘贴一个真实的抖音分享链接 (或按回车使用默认测试): ").strip()
        if user_link:
            test_share_links = [user_link]
    except KeyboardInterrupt:
        print("\n用户取消输入，使用默认测试链接")

    tester = SimpleDouyinTester()

    for i, share_link in enumerate(test_share_links, 1):
        print(f"\n🎯 测试链接 {i}:")
        print(f"📋 {share_link.strip()}")
        print("-" * 40)

        try:
            # 1. 测试链接解析
            print("🔍 步骤1: 解析分享链接")
            video_info = tester.parse_share_url(share_link)

            print(f"🎬 视频ID: {video_info['video_id']}")
            print(f"📝 标题: {video_info['title']}")
            print(f"🔗 下载链接: {video_info['url'][:80]}...")

            if 'error' in video_info:
                print(f"⚠️ 警告: {video_info['error']}")

            # 2. 测试视频访问
            print("\n📥 步骤2: 测试视频下载")
            download_success = tester.test_download_video(video_info)

            if download_success:
                print("🎉 视频链接有效，可以正常下载!")
            else:
                print("❌ 视频链接可能已失效或被限制访问")

            # 3. 测试 API 连接
            print("\n🔌 步骤3: 测试语音识别API")
            api_success = tester.test_api_connection()

            if api_success:
                print("🎉 语音识别 API 连接正常!")

            # 4. 测试替代方案
            print("\n🔄 步骤4: 测试替代API方案")
            tester.test_alternative_apis()

        except Exception as e:
            print(f"❌ 测试过程中出现错误: {str(e)}")
            print("🔍 错误详情:")
            import traceback
            traceback.print_exc()

        print("-" * 40)

    print("\n" + "=" * 60)
    print("✨ 测试完成!")

    print("\n📋 测试结果总结:")
    print("✅ 如果链接解析成功 → 基础功能正常")
    print("✅ 如果视频下载成功 → 可以获取视频文件")
    print("✅ 如果API连接成功 → 可以进行语音识别")

    print("\n🛠️  故障排除建议:")
    print("1. SSL错误 → 使用代理、VPN或更新网络配置")
    print("2. 403错误 → 更新User-Agent或使用不同IP")
    print("3. 解析失败 → 抖音页面结构可能已更新")
    print("4. API错误 → 检查API密钥和账户余额")

    print("\n🚀 下一步操作:")
    print("1. 如果测试通过，可以启动HTTP API服务:")
    print("   python http_api_wrapper.py")
    print("2. 在Dify中配置HTTP请求节点:")
    print("   POST http://localhost:5000/api/douyin/parse")
    print("3. 或者直接使用curl测试API:")
    print("""   curl -X POST http://localhost:5000/api/douyin/parse \\
     -H "Content-Type: application/json" \\
     -d '{"share_link": "你的抖音分享链接"}'""")

    print("\n💡 优化建议:")
    print("- 添加代理池轮换")
    print("- 实现更智能的重试机制")
    print("- 使用云函数部署避免IP限制")
    print("- 考虑使用第三方API服务")


if __name__ == "__main__":
    # 检查依赖
    required_modules = ['requests', 'urllib3']
    missing_modules = []

    for module in required_modules:
        try:
            __import__(module.replace('-', '_'))
            print(f"✅ {module} 已安装")
        except ImportError:
            missing_modules.append(module)

    if missing_modules:
        print(f"❌ 缺少依赖模块: {', '.join(missing_modules)}")
        print("请安装: pip install " + " ".join(missing_modules))
        exit(1)

    print("🎯 依赖检查完成，开始测试...\n")
    main()